package unibz.cn.logic;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.List;
import javax.swing.JOptionPane;
//For OAuthentication
import oauth.signpost.OAuthConsumer;
import oauth.signpost.basic.DefaultOAuthConsumer;
import oauth.signpost.signature.SignatureMethod;
//For parsing XML
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

/**
 * The class represents the user and contain all the methods for adding new tweets,
 * viewing the tweets and the followers, adding or removing friends.
 * 
 * @author Massimiliano Pergher, Abid
 */
public class User {
	//Application consumerKey and consumerSecret
	private static final String consumerKey = "7C6LburGp7wHAyy3gXYQ";
	private static final String consumerSecret = "bV40dZOxf4HEO9qHaz9QJ4V35N9AtNqJQ0hjX4eEVs";
	//User attributes
	private String username;
	private String password;
	private String accessToken;
	private String tokenSecret;
	OAuthConsumer consumer;
	
	/**
	 * Constructor of the class User. Given the username ad password it creates
	 * the user object retrieving from the xml files some data regarding the user
	 * 
	 * @param username The username of the user
	 * @param password The password of the user
	 */
	public User(String username, String password) {
		this.username = username;
		this.password = password;
		this.consumer = new DefaultOAuthConsumer(consumerKey,consumerSecret,SignatureMethod.HMAC_SHA1);;
		try {
			SAXReader reader = new SAXReader();
			Document document = reader.read(new java.io.File(".").getCanonicalPath()+"/users.xml");
			Element element = (Element)document.selectSingleNode("/users/user[username=\"" +username+ "\"]/password");
			boolean isRegistered = false;
		    if (element.getText().equals(password)) {
		   		isRegistered = true;
		   	}
			if (isRegistered) {
				element = (Element)document.selectSingleNode("/users/user[username=\"" +username+ "\"]/accesstoken");
				accessToken = element.getText();
				element = (Element)document.selectSingleNode("/users/user[username=\"" +username+ "\"]/tokensecret");
				tokenSecret = element.getText();
				consumer.setTokenWithSecret(accessToken, tokenSecret);
			}
		} catch (Exception e) {
			System.out.println(e);
		}
	}
	
	/**
	 * Used for the registration of a new user. Insert its data in the users.xml file.
	 * 
	 * @param username The username of the user
	 * @param password The password of the user
	 */
	public static void addUser(String username, String password) {
		try {
			SAXReader reader = new SAXReader();
			Document document = reader.read(new java.io.File(".").getCanonicalPath()+"/users.xml");
			Element rootElement = document.getRootElement(); 
			Element userElement	= rootElement.addElement("user");
			Element usernameElement = userElement.addElement("username");
			usernameElement.setText(username);
			Element passElement = userElement.addElement("password");
			passElement.setText(password);
			Element accesstoken = userElement.addElement("accesstoken");
			Element tokensecret = userElement.addElement("tokensecret");
			XMLWriter output = new XMLWriter( new FileWriter( new File(new java.io.File(".").getCanonicalPath()+"/users.xml") ));
		    output.write( document );
		    output.close();
		} catch (Exception e) {
			System.out.println(e);
		}
	}
	
	/**
	 * Check if the username and password provided exists in the XML file.
	 * 
	 * @param username The username of the user
	 * @param password The password of the user
	 * @return true if it is present and the data are correct, false otherwise
	 */
	public static boolean checkUser (String username, String password) {
		boolean isPresent = false;
		try {
			SAXReader reader = new SAXReader();
			Document document = reader.read(new java.io.File(".").getCanonicalPath()+"/users.xml");
			Element element = (Element)document.selectSingleNode("/users/user[username=\"" +username+ "\"]/password");
		    if (element.getText().equals(password)) {
		   		isPresent = true;
		   	}
		} catch (Exception e) {
			
		}
		return isPresent;
	}
	
	/**
	 * Post a message on twitter.
	 * 
	 * @param tweet The message to be posted on twitter
	 * @return a string with a success message
	 */
	public String addTweet (String tweet) {
		try {
			String encodedData = URLEncoder.encode(tweet, "UTF-8");
			URL url = new URL("http://api.twitter.com/1/statuses/update.xml?status="+ encodedData);
			HttpURLConnection request2 = (HttpURLConnection) url.openConnection();
			request2.setRequestMethod("POST");
			request2.setRequestProperty("Content-Length", "0");
			request2.setUseCaches(false);
			request2.setDoOutput(true);
			request2.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			this.getConsumer().sign(request2);
			request2.connect();
			BufferedReader in = new BufferedReader(new InputStreamReader(request2.getInputStream()));          
	        in.close();
		} catch (Exception e) {
			JOptionPane.showMessageDialog(null,"Problems with your tweet. Maybe it is too long or the server is down", "Attention",JOptionPane.ERROR_MESSAGE);
		}
		return "Tweet Succesfully Posted";
	}
	
	/**
	 * Given a name it adds this user to the list of people he follow. 
	 * 
	 * @param friendName The name of the user you want to follow
	 * @return a string with a success message
	 */
	public String follow (String friendName) {
		try {
			String encodedData = URLEncoder.encode(friendName, "UTF-8");
			URL url = new URL("http://api.twitter.com/1/friendships/create.xml?screen_name="+ encodedData);
			HttpURLConnection request2 = (HttpURLConnection) url.openConnection();
			request2.setRequestMethod("POST");
			request2.setRequestProperty("Content-Length", "0");
			request2.setUseCaches(false);
			request2.setDoOutput(true);
			request2.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			this.getConsumer().sign(request2);
			request2.connect();
			BufferedReader in = new BufferedReader(new InputStreamReader(request2.getInputStream()));          
	        in.close();
		} catch (Exception e) {
			System.out.println("bau");
			JOptionPane.showMessageDialog(null,"Problems in following the account. Maybe it does not exist", "Attention",JOptionPane.ERROR_MESSAGE);
			return"problem";
		}
		return "Now you follow " + friendName;
	}
	
	/**
	 * Delete a given user to the list of followed people  
	 *
	 * @param friendName The name of the user you want to follow
	 * @return a string with a success message
	 */
	public String unfollow(String friendName){
		try {
			String encodedData = URLEncoder.encode(friendName, "UTF-8");
			URL url = new URL("http://api.twitter.com/1/friendships/destroy.xml?screen_name="+ encodedData);
			HttpURLConnection request2 = (HttpURLConnection) url.openConnection();
			request2.setRequestMethod("POST");
			request2.setRequestProperty("Content-Length", "0");
			request2.setUseCaches(false);
			request2.setDoOutput(true);
			request2.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			this.getConsumer().sign(request2);
			request2.connect();
			BufferedReader in = new BufferedReader(new InputStreamReader(request2.getInputStream()));
	        in.close();
		} catch (Exception e) {
			JOptionPane.showMessageDialog(null,"You have not a friend with such a name", "Attention",JOptionPane.ERROR_MESSAGE);
		}
		return "Now you don't follow " + friendName + " anymore";
	}
	
	/**
	 * Display the tweets
	 * 
	 * @return a List with a the last 20 tweets
	 */
	public List getTweets() throws Exception{
		URL url = new URL("http://twitter.com/statuses/friends_timeline.xml");
		URLConnection request = (HttpURLConnection) url.openConnection();
		this.getConsumer().sign(request);
		request.connect();
		SAXReader reader = new SAXReader();
		Document document = reader.read(new InputStreamReader(request.getInputStream()));
		List list = document.selectNodes("/statuses/status");
		return list;
	}
	
	/**
	 * Display the friends of the user
	 * 
	 * @return a List containing all the followed friends
	 */
	public List getFriends() throws Exception{
		URL url = new URL("http://api.twitter.com/1/statuses/friends.xml");
		URLConnection request = (HttpURLConnection) url.openConnection();
		this.getConsumer().sign(request);
		request.connect();
		SAXReader reader = new SAXReader();
		Document document = reader.read(new InputStreamReader(request.getInputStream()));
		List list = document.selectNodes("/users/user");
		return list;
	}
	
	public String getUsername() {
		return this.username;
	}
	
	public String getPassword() {
		return this.password;
	}
	
	public String getAccessToken() {
		return this.accessToken;
	}
	
	public String getTokenSecret() {
		return this.tokenSecret;
	}
	
	public OAuthConsumer getConsumer() {
		return this.consumer;
	}
	
	public void setUsername(String username) {
		this.username = username;
	}
	
	public void setPassword(String password) {
		this.password = password;
	}
	
	public void setAccessToken(String accessToken) {
			this.accessToken = accessToken;
	}
	
	public void setTokenSecret(String tokenSecret) {
		this.tokenSecret = tokenSecret;
	}
	
	public void setConsumer(OAuthConsumer consumer) {
		this.consumer = consumer;
	}
}
